package com.benew.ntt.ydeval

import android.util.Base64.encodeToString
import com.benew.ntt.evaluate.constant.EvalError
import com.benew.ntt.evaluate.constant.EvalType
import com.benew.ntt.evaluate.sdk.EvalSDKEntity
import com.benew.ntt.evaluate.sdk.EvalSDKHandler
import com.benew.ntt.ydeval.constant.YDEvalConst
import com.benew.ntt.ydeval.listener.RecordStreamListener
import com.benew.ntt.ydeval.utils.EvalUtils
import com.blankj.utilcode.util.EncodeUtils
import com.ntt.core.nlogger.NLogger
import okhttp3.*
import okhttp3.logging.HttpLoggingInterceptor
import java.io.FileInputStream
import java.io.IOException
import java.io.InputStream
import java.text.SimpleDateFormat
import java.util.*
import java.util.concurrent.TimeUnit


class SHttpClient(private var entity: EvalSDKEntity) {
    companion object {
        private val TAG = SHttpClient::class.java.simpleName
    }

    var mSDKHandler: EvalSDKHandler? = null
    var mCall: Call? = null

    //录音监听
    private val mRecordStreamListener = object : RecordStreamListener {
        override fun recordOfByte(data: ByteArray, begin: Int, end: Int, decibel: Double) {
            try {
                mSDKHandler?.recordOfByte(data, begin, end, decibel)
            } catch (e: Exception) {
                NLogger.e(TAG, "发送数据异常=${e.message}")
            }
        }

        override fun recordPath(path: String) {
            NLogger.d(TAG, "结束录音路径=$path")
            mSDKHandler?.sendRecordFile(path)
            doRequest(path)
        }

        override fun onEndRecord() {
            NLogger.d(TAG, "结束录音！！！")
            mSDKHandler?.sendRecordEnd()
        }

        override fun startRecord() {
            super.startRecord()
            NLogger.d(TAG, "开始录音！！！")
            mSDKHandler?.sendStartRecord()
        }
    }

    /**
     * 开始录音
     */
    private fun startRecord() {
        NLogger.e(TAG, "打开录音！！！")
        // 初始化录音
        val fileName = SimpleDateFormat("yyyyMMddhhmmss").format(Date())
        CmAudioRecorder.getInstance().createDefaultAudio(fileName)
        CmAudioRecorder.getInstance().startRecord(mRecordStreamListener)
    }

    /**
     * 停止录音
     */
    fun stopRecord() {
        CmAudioRecorder.getInstance().stopRecord()
    }

    /**
     * 释放资源
     */
    fun releaseRes() {
        if (mSDKHandler != null) {
            mSDKHandler?.removeCallbacksAndMessages(null)
            mSDKHandler = null
        }
        try {
            CmAudioRecorder.getInstance().setListener(null)
            CmAudioRecorder.getInstance().release()
        } catch (e: Exception) {
            NLogger.e(TAG, "录音关闭异常！！！", e.message)
        }
        mCall?.cancel()
    }

    private fun loadAsBase64(filename: String?): String? {
        var inputS: InputStream? = null
        var data: ByteArray? = null
        try {
            inputS = FileInputStream(filename)
            data = ByteArray(inputS.available())
            inputS.read(data)
            inputS.close()
        } catch (e: IOException) {
            e.printStackTrace()
        }
        return EncodeUtils.base64Encode2String(data)
    }

    private fun truncate(q: String?): String? {
        if (q == null) {
            return null
        }
        val len = q.length
        return if (len <= 20) q else q.substring(0, 10) + len + q.substring(len - 10, len)
    }

    private fun doRequest(filePath: String?) {
        if (filePath.isNullOrBlank()) {
            NLogger.d(TAG, "录音文件没有")
            mSDKHandler?.sendError(null, EvalError.ERROR_4)
            return
        }
        NLogger.d(TAG, "请求评分")

        val salt = UUID.randomUUID().toString()
        val curtime = (System.currentTimeMillis() / 1000).toString()
        val q = loadAsBase64(filePath) ?: ""

        val requestBody =
            MultipartBody.Builder().setType(MultipartBody.FORM)
                .addFormDataPart("text", entity.content ?: "")
                .addFormDataPart("langType", EvalType.ZH_CHS)
                .addFormDataPart("appKey", YDEvalConst.APP_KEY)
                .addFormDataPart("format", "wav")
                .addFormDataPart("rate", "16000")
                .addFormDataPart("channel", "1")
                .addFormDataPart("docType", "json")
                .addFormDataPart("type", "1")
                .addFormDataPart("salt", salt)
                .addFormDataPart("curtime", curtime)
                .addFormDataPart("signType", "v2")
                .addFormDataPart("q", q)
                .addFormDataPart(
                    "sign",
                    EvalUtils.getDigest(YDEvalConst.APP_KEY + truncate(q).toString() + salt + curtime + YDEvalConst.APP_SECRET)
                )
                .build()
        val request = Request.Builder()
            .url(YDEvalConst.URL)
            .post(requestBody)
            .build()
        val okHttpClient = OkHttpClient.Builder()
            .connectTimeout(10, TimeUnit.SECONDS)
            .readTimeout(10, TimeUnit.SECONDS)
            .writeTimeout(10, TimeUnit.SECONDS)
            .callTimeout(10, TimeUnit.SECONDS)
            .addInterceptor(HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BODY))
            .build()

        mCall = okHttpClient.newCall(request)

        mCall?.enqueue(object : Callback {
            override fun onFailure(call: Call, e: IOException) {
                NLogger.d(TAG, "请求失败")
                mSDKHandler?.sendError(null, EvalError.ERROR_5)

            }

            override fun onResponse(call: Call, response: Response) {
                val result = response.body()?.string()
                NLogger.d(TAG, "请求成功", response.code(), result)
                mSDKHandler?.sendResult("{\"result\":$result}")
            }
        })
    }


    fun start() {
        NLogger.d(TAG, "start")
        startRecord()
        mSDKHandler?.sendRecordTimeOutCountDown(10000)
    }
}